#define _CRT_SECURE_NO_WARNINGS 1
#include"string.h"
namespace bit
{
	const  size_t string::npos = -1;

	string::string(const char* str)
		:_size(strlen(str))
	{
		_str = new char[_size + 1];
		_capacity = _size;
		strcpy(_str, str);
	}
	string::string(const string& str)
	{
		_str = new char[str._size + 1];
		strcpy(_str, str._str);
		_size = str._size;
		_capacity = str._capacity;
	}
	string& string::operator=(const string& str)
	{
		_str = new char[str._size + 1];
		strcpy(_str, str._str);
		_size = str._size;
		_capacity = str._capacity;
		return *this;
	}
	string::	~string()
	{
		if (_str)
		{
			delete[]_str;
			_str = nullptr;
			_size = _capacity = 0;
		}
	}
	const char* string::c_str()
	{
		return _str;
	}
	/*ostream& operator<<(ostream& out, const string& str)
	{
		out << str._str;
		return out;
	}*/
	string:: iterator string:: begin()
	{
		return _str;
	}
	string:: iterator string:: end()
	{
		return _str + _size;
	}
	int string::size()const
	{
		return _size;
	}

	char& string::operator[](size_t pos) 
	{
		assert(pos < _size);
		return _str[pos];
	}
	void string::reserve(int n)
	{
		if (n > _capacity)
		{
			char* tmp = new char[n + 1];
			strcpy(tmp, _str);
			delete[]_str;
			_str = tmp;
			_capacity = n;
		}
	}
	void string:: push_back(const char c)
	{
		if (_size == _capacity)
		{
			int newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
			reserve(newcapacity);

		}
		_str[_size++] = c;
		_str[_size] = '\0';
	}
	void string::append(const char* str)
	{
		int len = strlen(str);
		reserve(len + _size);
		strcpy(_str+_size, str);
		_size += len;
	}
	string& string::operator+=(char c)
	{
		push_back(c);
		return*this;
	}
	string& string::operator+=(const char* str)
	{
		append(str);
		return *this;
	}
	void string::insert(size_t pos, char c)
	{
		assert(pos <= _size);
		if (_size == _capacity)
		{
			int newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
			reserve(newcapacity);

		}
		int end = _size + 1;
		while (end > pos)
		{
			_str[end] = _str[end - 1];
			
			end--;
		}
		_str[pos] = c;
		_size++;
	}
	void string::insert(size_t pos, const char* str)
	{
		assert(pos <= _size);
		int len = strlen(str);
		reserve(_size + len);

		int end = _size + len;
		while (end > pos+len-1)
		{
			_str[end] = _str[end - len];
			end --;
		}
		memcpy(_str + pos, str, len);
		_size += len;
	}
	void string::erage(int pos, size_t len)
	{
		if (len > _size - pos)
		{
			_str[pos] = '\0';
			_size = pos;
		}
		else
		{
			strcpy(_str + pos, _str + pos + len);
			_size -= len;
		}
	}
	int string::find(char c, int pos)
	{
		assert(pos <= _size);
		for (int i = pos; i <=_size; i++)
		{
			if (_str[i] == c)
			{
				return i;
			}
		}
		return npos;
	}
	int string::find(const char* str, int pos)
	{
		char* p = strstr(_str + pos, str);
		return p - _str;
	}
	void string:: Swap( string& str)
	{
		swap(_str, str._str);
		swap(_size, str._size);
		swap(_capacity, str._capacity);
	}
	string string::substr(int pos, int len)
	{
		if (len > _size - pos)
		{
			string s(_str+pos);
			return s;
		}
		string s;
		s.reserve(len);
		for (int i = 0; i < len; i++)
		{
			
			s += _str[pos+i];
		}
		
		return s;
	}
	bool string::operator<(const string& str)const
	{
		return strcmp(_str, str._str) < 0;
	}
	bool string::operator<=(const string& str)const
	{
		return *this < str && *this == str;
	}
	bool string::operator==(const string& str)const
	{
		return strcmp(_str, str._str) == 0;

	}
	bool string:: operator>(const string& str)const
	{
		return !(*this <= str);
	}
	bool string::operator>=(const string& str)const
	{
		return !(*this < str);
	}
	bool string::operator!=(const string& str)const
	{

		return !(*this == str);
	}
	ostream& operator<< (ostream& out,  string& str)
	{
		for (size_t i = 0; i < str.size(); i++)
		{
			out << str[i];
		}

		return out;
	}
	void string::clear()
	{
		_str[0] = '\0';
		_size = 0;
	}

	istream& operator>>(istream& in,  string& str)
	{
		str.clear();
		char ch;
	    in.get(ch);
		str += ch;
		while (ch != ' ' && ch != '\n')
		{
			ch = in.get();
			str += ch;
		}
		return in;
	}
}
